package com.fenghuaxz.rpcframework;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.MessageToByteEncoder;
import io.netty.handler.timeout.IdleStateHandler;
import java.net.InetSocketAddress;

/**
 * 创建 : 七羽软件工作室
 * 时间 : 2017/9/28 : 1:09
 */
public class RPCServer extends BaseContext{

    private final ServerBootstrap sb = new ServerBootstrap();
    private final EventLoopGroup bossGroup = new NioEventLoopGroup();
    private final EventLoopGroup workerGroup = new NioEventLoopGroup();

    public RPCServer(){
        sb.group(bossGroup,workerGroup);
        sb.channel(NioServerSocketChannel.class);
        sb.option(ChannelOption.SO_BACKLOG,128);
        sb.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
        sb.childOption(ChannelOption.ALLOCATOR,PooledByteBufAllocator.DEFAULT);
        sb.childOption(ChannelOption.TCP_NODELAY,true);
        sb.childHandler(new ChannelInitializer<NioSocketChannel>() {
            @Override
            protected void initChannel(NioSocketChannel channel) throws Exception {
                if (BaseContext.encoder == null || BaseContext.decoder == null)
                    throw new NullPointerException("encoder or decoder");
                else{
                    ChannelPipeline pipeline=channel.pipeline();
                    MessageToByteEncoder encoder = BaseContext.encoder.newInstance();
                    ByteToMessageDecoder decoder = BaseContext.decoder.newInstance();
                    pipeline.addLast(encoder,decoder);
                    pipeline.addLast(new IdleStateHandler(10,5,20));
                    pipeline.addLast(new ServerBootstrapInBoundHandler(RPCServer.this));
                }
            }
        });
    }

    @Override
    public BaseContext bind(InetSocketAddress address) throws Exception {
        return open(sb,address);
    }

    @Override
    public void close() {
        this.group.close();
        this.bossGroup.shutdownGracefully();
        this.workerGroup.shutdownGracefully();
    }
}
